﻿using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using GPainter.Data;
using GPainter.Events;
using GPainter.Interfaces;
using GPainter.ModelViewPresenter;
using Point = GPainter.Data.Point;

namespace GPainter
{
    public partial class GraphControl
    {
        //private const int CanvasHeight = 5000;
        //private const int CanvasWidth = 5000;
        //вот на это то и подписываемся!!!!
        public event EventHandler<NodeAddEventArgs> OnAddNewNode;
        public event EventHandler<EdgeAddEventArgs> OnAddNewEdge;
        public event EventHandler<NodeAddEventArgs> OnSelectNode;
        public event EventHandler<NodeDeleteEventArgs> OnDeleteNode;//удаление вершины
        public event EventHandler<EdgeDeleteEventArgs> OnDeleteEdge;//удаление дуги
        public event EventHandler<EventArgs> OnChangeMultipleMode;
        public event EventHandler<EventArgs> OnDeselectAllNodes;

        public GraphControl()
        {
            InitializeComponent();
            Start();
        }

        Presenter _presentor;//ссылка на презентор
        View _view;//ссылка на представление

        public void Start()//
        {
            
            //создаем презентор и пихаем в него поверхность для рисования
            _view = new View(cnvsMain);
            _presentor = new Presenter(_view);
            //регистрируем стандартный тип вершины
            //NodeDataViewManager.RegisterNode();

            //подписываемся на события презентора
            _presentor.OnAddNewNode += presentor_OnAddNewNode;
            _presentor.OnAddNewEdge += presentor_OnAddNewEdge;
            _presentor.onSelectNode += presentor_onSelectNode;
            _presentor.onDeleteNode += presentor_onDeleteNode;
            _presentor.onDeleteEdge += presentor_onDeleteEdge;
            _presentor.OnChangeOperation += presentor_OnChangeOperation;
            _presentor.OnDeselectAll += presentor_OnDeselectAll;
            //добавляем элемент меню для добавления сущности
            var mnAddNode = new MenuItem {Header = "Добавить сущность..."};
            mnAddNode.Click += mnAddNode_Click;
            cnvsMain.ContextMenu.Items.Add(mnAddNode);
           // presentor.InitGraph();
            //рисуем граф
            _presentor.StartGraphDrawing();
            // presentor.SetOperation("Move");
            

        }

        /// <summary>
        /// зарегистрировать вершину
        /// </summary>
        /// <param name="nodeTypeName">имя типа вершины в целом</param>
        /// <param name="dataType">тип данных описывающий вершину</param>
        /// <param name="viewType">тип представления описывающий вершину</param>
        public void RegisterNode(string nodeTypeName, Type dataType, Type viewType)
        {
            //TODO проверки на реализацию интерфейсов INodeData, INodeView и на наличие уже зарегистрированного такого типа
            NodeDataViewManager.RegisterNode(nodeTypeName,dataType,viewType);
        }

        private void mnAddNode_Click(object sender, RoutedEventArgs e)
        {
            _newNodeCount++;
            var r = new Random(1);
            var visualTree = new MyTreeViewItem
                                 {
                                     Header = "1",
                                     Childs = new List<MyTreeViewItem>
                                                  {
                                                      new MyTreeViewItem {Header = "2"}
                                                  }
                                 };
            AddNewNode(new NodeData
                (_newNodeCount.ToString(), _newNodeCount.ToString(),
                new HelpRect(100, 50), new Point(r.Next(100, 500), r.Next(100, 500)), visualTree
                ));
        }

        private int _newNodeCount;

        void presentor_OnDeselectAll(object sender, EventArgs e)
        {
            if (OnDeselectAllNodes != null)
            {
                OnDeselectAllNodes(this, new EventArgs());
            }
        }

        void presentor_OnChangeOperation(object sender, OperationEventArgs e)
        {

        }

        void presentor_onDeleteEdge(object sender, EdgeDeleteEventArgs e)
        {
            if (OnDeleteEdge != null)
                OnDeleteEdge(this, e);
        }

        void presentor_onDeleteNode(object sender, NodeDeleteEventArgs e)
        {
            if (OnDeleteNode != null)
                OnDeleteNode(this, e);
        }

        void presentor_onSelectNode(object sender, NodeAddEventArgs e)
        {
            if (OnSelectNode != null)
                OnSelectNode(this, e);
        }

        void presentor_OnAddNewEdge(object sender, EdgeAddEventArgs e)
        {
            if (OnAddNewEdge != null)
                OnAddNewEdge(this, e);
        }

        //обработчик события из  презентора : добавлена новая вершина на представление
        void presentor_OnAddNewNode(object sender, NodeAddEventArgs e)
        {
            if (OnAddNewNode != null)
                OnAddNewNode(this, e);
        }

        //добавление новой вершины
        public void AddNewNode(INodeData n)
        {
            _presentor.AddNodeToModel(n);

        }

        //добавление новой дуги
        public void AddNewEdge(IEdgeData edge)
        {
            _presentor.AddEdgeToModel(edge);
        }

        //выделение вершины 
        public void SelectNode(string ID)
        {
            _presentor.SelectNode(ID);
        }

        //удаление вершины
        public void DeleteNode(string ID)
        {
            _presentor.DeleteNodeFromModel(ID);
        }

        //удалить все вершины
        public void DeleteAllNodes()
        {
            _presentor.DeleteAllNodes();

        }

        //удаление вершины
        public void DeleteEdge(string ID)
        {
            _presentor.DeleteEdge(ID);
        }


        //обновление инофрмации о вершине
        public void UpdateNodeInfo(string lastID, INodeData newNode)
        {
            _presentor.RefreshNodeInfo(lastID, newNode);
        }

        //удаление всех дуг
        public void ClearAllEdges()
        {
            _presentor.DeleteAllEdgesFromModel();
        }

        public Point GetCoords(string ID)
        {
            return (_presentor.GetNodeInfo(ID).Pos);
        }

        public INodeData GetNodeInfo(string ID)
        {
            return (_presentor.GetNodeInfo(ID));
        }

        //обновить количеcтво вершин
        public void updateNodeCount(int c)
        {
            Count = c;
            _presentor.UpdateNodeCount(c);
        }

        public string GetSelectedNodeId()
        {
            return _presentor.SelectedNodeId;
        }


        private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (_presentor != null)
            {
                cnvsMain.RenderTransform = null;
                switch ((sender as ComboBox).SelectedIndex)
                {

                    case 0:
                        cnvsMain.RenderTransform = new ScaleTransform(0.5, 0.5);
                        //cnvsMain.Width = canvasHeight / 2;
                        //cnvsMain.Height = canvasWidth / 2;
                        //   MessageBox.Show(cnvsMain.ActualHeight.ToString());
                        break;
                    case 1:
                        cnvsMain.RenderTransform = new ScaleTransform(0.75, 0.75);
                        //cnvsMain.Width = canvasHeight * 0.75;
                        //cnvsMain.Height = canvasWidth * 0.75;
                        break;
                    case 2:
                        cnvsMain.RenderTransform = new ScaleTransform(1, 1);
                        //cnvsMain.Width = canvasHeight;
                        //cnvsMain.Height = canvasWidth;
                        break;
                    case 3:
                        cnvsMain.RenderTransform = new ScaleTransform(1.25, 1.25);
                        //cnvsMain.Width = canvasHeight * 1.25;
                        //cnvsMain.Height = canvasWidth * 1.25;
                        break;
                    case 4:
                        cnvsMain.RenderTransform = new ScaleTransform(1.5, 1.5);
                        //cnvsMain.Width = canvasHeight * 1.5;
                        //cnvsMain.Height = canvasWidth * 1.5;
                        break;
                }
            }
        }

        public int Count;


        private void btnMultySelect_Click(object sender, RoutedEventArgs e)
        {
            //мультиселект
            if (_presentor == null) return;
            if (btnMultySelect.IsChecked.Value)
            {

                _presentor.SetMultySelect(true);
                if (OnChangeMultipleMode != null)
                    OnChangeMultipleMode(this, new EventArgs());
            }
            else
            {
                _presentor.SetMultySelect(false);
                if (OnChangeMultipleMode != null)
                    OnChangeMultipleMode(this, new EventArgs());
            }
        }



    }
}
